home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / VIS082S.ARJ / WINTTT5.PAS < prev    next >
Pascal/Delphi Source File  |  1989-09-30  |  29KB  |  991 lines

  1. {--------------------------------------------------------------------------}
  2. {                         TechnoJock's Turbo Toolkit                       }
  3. {                                                                          }
  4. {                              Version   5.02                              }
  5. {                                                                          }
  6. {                                                                          }
  7. {              Copyright 1986, 1989 TechnoJock Software, Inc.              }
  8. {                           All Rights Reserved                            }
  9. {                          Restricted by License                           }
  10. {--------------------------------------------------------------------------}
  11.  
  12.                      {--------------------------------}
  13.                      {       Unit:   WinTTT5          }
  14.                      {--------------------------------}
  15.  
  16. {History:    03/05/89   5.00a  corrected Get_ScreenWord procedure
  17.              04/01/89   5.01   added DOS errorlevel 10 on fatal
  18.                                and corrected screen scroll
  19.                         5.01a  added DEBUG compiler directive
  20. }
  21.  
  22. {$S-,R-,V-}
  23. {$IFNDEF DEBUG}
  24. {$D-}
  25. {$ENDIF}       
  26.  
  27. unit  WinTTT5;
  28.  
  29. interface
  30.  
  31. uses CRT,DOS,FastTTT5,KeyTTT5;
  32.  
  33. Type
  34.  Direction = (Up, Down, Left, Right);
  35. Const
  36.     Shadow = 5;
  37. Var
  38.     Shadcolor    : byte;
  39.     DisplayLines : byte;
  40.  
  41. Procedure MoveFromScreen(var Source,Dest;Length:Word);
  42. Procedure MoveToScreen(var Source,Dest; Length:Word);
  43. Procedure SizeCursor(Top,Bot:byte);
  44. Procedure FindCursor(var X,Y,Top,Bot:byte);
  45. Procedure PosCursor(X,Y: integer);
  46. Procedure Fullcursor;
  47. Procedure HalfCursor;
  48. Procedure OnCursor;
  49. Procedure OffCursor;
  50. Procedure GotoXY(X,Y : byte);
  51. Function  WhereX: byte;
  52. Function  WhereY: byte;
  53. Function  GetScreenChar(X,Y:byte):char;
  54. Function  GetScreenAttr(X,Y:byte):byte;
  55. Procedure GetScreenStr(X1,X2,Y:byte;var  St:StrScreen);
  56. Procedure CreateScreen(Page:byte;Lines:byte);
  57. Procedure SaveScreen(Page:byte);
  58. Procedure RestoreScreen(Page:byte);
  59. Procedure PartRestoreScreen(Page,X1,Y1,X2,Y2,X,Y:byte);
  60. Procedure SlideRestoreScreen(Page:byte;Way:Direction);
  61. Procedure PartSlideRestoreScreen(Page:byte;Way:Direction;X1,Y1,X2,Y2:byte);
  62. Procedure DisposeScreen(Page:byte);
  63. Procedure SetCondensedLines;
  64. Procedure Set25Lines;
  65. Procedure CopyScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
  66. Procedure MoveScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
  67. Procedure Scroll(Way:direction;X1,Y1,X2,Y2:byte);
  68. Procedure PartSave(X1,Y1,X2,Y2:byte; VAR Dest);
  69. Procedure PartRestore(X1,Y1,X2,Y2:byte; VAR Source);
  70. Procedure Mkwin(x1,y1,x2,y2,F,B,boxtype:integer);
  71. Procedure GrowMkwin(x1,y1,x2,y2,F,B,boxtype:integer);
  72. Procedure Rmwin;
  73. Procedure FillScreen(X1,Y1,X2,Y2:byte; F,B:byte; C:char);
  74. Procedure TempMessageCh(X,Y,F,B:integer;St:strscreen;var Ch : char);
  75. Procedure TempMessage(X,Y,F,B:integer;St:strscreen);
  76. Procedure TempMessageBoxCh(X1,Y1,F,B,BoxType:integer;St:strscreen;var Ch : char);
  77. Procedure TempMessageBox(X1,Y1,F,B,BoxType:integer;St:strscreen);
  78. Procedure Activate_Visible_Screen;
  79. Procedure Activate_Virtual_Screen(Page:byte);
  80. Procedure Reset_StartUp_Mode;
  81.  
  82. Const
  83.     Max_Windows = 10;          {Change this constant as necessary}
  84.     Max_Screens = 10;          {Change this constant as necessary}
  85.     WindowCounter : byte = 0;
  86.     ScreenCounter : byte = 0;
  87.     ActiveVScreen: byte = 0;
  88.  
  89. Type
  90.     ScreenImage = record
  91.                        CursorX : byte;
  92.                        CursorY : byte;
  93.                        ScanTop : byte;
  94.                        ScanBot : byte;
  95.                        SavedLines:byte;
  96.                        ScreenPtr: pointer;
  97.                   end;
  98.     ScreenPtr = ^ScreenImage;
  99.     WindowImage = record
  100.                        ScreenPtr: Pointer;             {pointer to screen data}
  101.                        Coord    : array[1..4] of byte; {window coords}
  102.                        CursorX  : byte;                {cursor location}
  103.                        CursorY  : byte;
  104.                        ScanTop  : byte;                {cursor shape}
  105.                        ScanBot  : byte;
  106.                   end;
  107.     WindowPtr = ^WindowImage;
  108.  
  109. Var
  110.     Screen : array[1..Max_Screens] of ScreenPtr;
  111.     Win    : array[1..Max_Windows] of WindowPtr;
  112.     W_error: integer;     {Global error to report winTTT errors}
  113.     W_fatal: boolean;
  114.  
  115. IMPLEMENTATION
  116.  
  117. CONST
  118.     MonoAdr =$b000;
  119. VAR
  120.     StartTop,      {used to record initial screen state when program is run}
  121.     StartBot   : Byte;
  122.     StartMode  : word;
  123.  
  124. {$L WINTTT5}
  125.  
  126. {$F+}
  127.   Procedure MoveFromScreen(var Source,Dest;Length:Word); external;
  128.   Procedure MoveToScreen(var Source,Dest; Length:Word); external;
  129. {$F-}
  130.  
  131. Procedure WinTTT_Error(No : byte);
  132. {Updates W_error and optionally displays error message then halts program}
  133. var Msg : String;
  134. begin
  135.     W_error := No;
  136.     If W_fatal = true then
  137.     begin
  138.         Case No of
  139.         1 :  Msg := 'Max screens exceeded';
  140.         2 :  Msg := 'Max Windows Exceeded';
  141.         3 :  Msg := 'Insufficient memory to create screen';
  142.         4 :  Msg := 'Screen not saved cannot activate.';
  143.         5 :  Msg := 'Screen has not been created - cannot activate';
  144.         6 :  Msg := 'Screen has not been created - cannot dispose';
  145.         7 :  Msg := 'Screen has not been created - cannot restore';
  146.         8 :  Msg := 'Screen does not exist cannot clear';
  147.         9 :  Msg := 'Insufficient memory for Screen Copy/Move';
  148.         10:  Msg := 'Visible screen must be active for Window operations';
  149.         11:  Msg := 'Visible screen must be active for Message operations';
  150.         12:; {reserved for non-fatal error settings condensed mode}
  151.         13:  Msg := 'Can only save 25 screen lines - check CONST SavedLines';
  152.         else Msg := '?) -- Utterly confused';
  153.         end; {Case}
  154.         Msg := 'Fatal Error (WinTTT -- '+Msg;
  155.         Writeln(Msg);
  156.         Delay(5000);    {display long enough to read if child process}
  157.         Halt(11);       {returns DOS ERRORLEVEL 11}
  158.     end;
  159. end;
  160.  
  161. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  162. {                                                                     }
  163. {     V I S I B L E    a n d    V I R T U A L  P R O C E D U R E S    }
  164. {                                                                     }
  165. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  166. Procedure PartSave (X1,Y1,X2,Y2:byte; VAR Dest);
  167. {transfers data from active virtual screen to Dest}
  168. var
  169.    I,width : byte;
  170.    ScreenAdr: integer;
  171. begin
  172.     width := succ(X2- X1);
  173.     For I :=  Y1 to Y2 do
  174.     begin
  175.      ScreenAdr := Vofs + Pred(I)*160 + Pred(X1)*2;
  176.      MoveFromScreen(Mem[Vseg:ScreenAdr],
  177.                     Mem[seg(Dest):ofs(dest)+(I-Y1)*width*2],
  178.                     width);
  179.     end;
  180. end;
  181.  
  182. Procedure PartRestore (X1,Y1,X2,Y2:byte; VAR Source);
  183. {restores data from Source and transfers to active virtual screen}
  184. var
  185.    I,width : byte;
  186.    ScreenAdr: integer;
  187. begin
  188.     width := succ(X2- X1);
  189.     For I :=  Y1 to Y2 do
  190.     begin
  191.      ScreenAdr := Vofs + Pred(I)*160 + Pred(X1)*2;
  192.      MoveToScreen(Mem[Seg(Source):ofs(Source)+(I-Y1)*width*2],
  193.                   Mem[Vseg:ScreenAdr],
  194.                   width);
  195.     end;
  196. end;
  197.  
  198. Procedure FillScreen(X1,Y1,X2,Y2:byte; F,B:byte; C:char);
  199. var
  200.    I : integer;
  201.    S : string;
  202. begin
  203.     W_error := 0;
  204.     Attrib(X1,Y1,X2,Y2,F,B);
  205.     S := Replicate(Succ(X2-x1),C);
  206.     For I := Y1 to Y2 do
  207.         PlainWrite(X1,I,S);
  208. end;
  209.  
  210. Procedure GetScreenWord(X,Y:byte;var Attr:byte; var Ch : char);
  211. {updates vars Attr and Ch with attribute and character bytes in screen
  212.  location (X,Y) of the active screen}
  213. Type
  214.     ScreenWordRec = record
  215.                          Ch   : char;   {5.00a}
  216.                          Attr : byte;
  217.                     end;
  218. var
  219.    ScreenAdr: integer;
  220.    SW : ScreenWordRec;
  221. begin
  222.     ScreenAdr := Vofs + Pred(Y)*160 + Pred(X)*2;
  223.     MoveFromScreen(Mem[Vseg:ScreenAdr],mem[seg(SW):ofs(SW)],1);
  224.     Attr := SW.Attr;
  225.     Ch   := SW.Ch;
  226. end;
  227.  
  228. Function GetScreenChar(X,Y:byte):char;
  229. var
  230.    A : byte;
  231.    C : char;
  232. begin
  233.     GetScreenWord(X,Y,A,C);
  234.     GetScreenChar := C;
  235. end;
  236.  
  237. Function GetScreenAttr(X,Y:byte):byte;
  238. var
  239.    A : byte;
  240.    C : char;
  241. begin
  242.     GetScreenWord(X,Y,A,C);
  243.     GetScreenAttr := A;
  244. end;
  245.  
  246. Procedure GetScreenStr(X1,X2,Y:byte;var  St:StrScreen);
  247. var
  248.    I : integer;
  249. begin
  250.     St := '';
  251.     For I := X1 to X2 do
  252.         St := St + GetScreenChar(I,Y);
  253. end;
  254.  
  255. {++++++++++++++++++++++++++++++++++++++++++++++}
  256. {                                              }
  257. {         C U R S O R    R O U T I N E S       }
  258. {                                              }
  259. {++++++++++++++++++++++++++++++++++++++++++++++}
  260.  
  261. Procedure GotoXY(X,Y : byte);
  262. {intercepts normal Turbo GotoXY procedure, in case a virtual screen
  263.  is active.
  264. }
  265. begin
  266.     If VSeg = BaseOfScreen then
  267.        CRT.GotoXY(X,Y)
  268.     else
  269.        with Screen[ActiveVScreen]^ do
  270.        begin
  271.            CursorX := X;
  272.            CursorY := Y;
  273.        end; {with}
  274. end;  {proc GotoXY}
  275.  
  276. Function WhereX: byte;
  277. {intercepts normal Turbo WhereX procedure, in case a virtual screen
  278.  is active.
  279. }
  280. begin
  281.     If VSeg = BaseOfScreen then
  282.        WhereX := CRT.WhereX
  283.     else
  284.        with Screen[ActiveVScreen]^ do
  285.            WhereX := CursorX;
  286. end; {of func WhereX}
  287.  
  288. Function WhereY: byte;
  289. {intercepts normal Turbo WhereX procedure, in case a virtual screen
  290.  is active.
  291. }
  292. begin
  293.     If VSeg = BaseOfScreen then
  294.        WhereY := CRT.WhereY
  295.     else
  296.        with Screen[ActiveVScreen]^ do
  297.            WhereY := CursorY;
  298. end; {of func WhereY}
  299.  
  300. Procedure FindCursor(var X,Y,Top,Bot:byte);
  301. var
  302.    Reg : registers;
  303. begin
  304.   If VSeg = BaseOfScreen then    {visible screen is active}
  305.   begin   
  306.       Reg.Ax := $0F00;              {get page in Bx}
  307.       Intr($10,Reg);
  308.       Reg.Ax := $0300;
  309.       Intr($10,Reg);
  310.       With Reg do
  311.       begin
  312.         X := lo(Dx) + 1;
  313.         Y := hi(Dx) + 1;
  314.         Top := Hi(Cx) and $0F;
  315.         Bot := Lo(Cx) and $0F;
  316.       end;
  317.   end
  318.   else                            {virtual screen active}
  319.      with Screen[ActiveVScreen]^ do
  320.      begin
  321.          X := CursorX;
  322.          Y := CursorY;
  323.          Top := ScanTop;
  324.          Bot := ScanBot;
  325.      end;
  326. end;
  327.  
  328. Procedure PosCursor(X,Y: integer);
  329. var Reg : registers;
  330. begin
  331.     If VSeg = BaseOfScreen then    {visible screen is active}
  332.     begin   
  333.         Reg.Ax := $0F00;              {get page in Bx}
  334.         Intr($10,Reg);
  335.         with Reg do
  336.         begin
  337.           Ax := $0200;
  338.           Dx := ((Y-1) shl 8) or ((X-1) and $00FF);
  339.         end;
  340.         Intr($10,Reg);
  341.     end
  342.     else                           {virtual screen active}
  343.        with Screen[ActiveVScreen]^ do
  344.        begin
  345.            CursorX := X;
  346.            CursorY := Y;
  347.        end;
  348. end;
  349.  
  350. Procedure SizeCursor(Top,Bot:byte);
  351. var Reg : registers;
  352. begin
  353.     If VSeg = BaseOfScreen then    {visible screen is active}
  354.        with Reg do
  355.        begin
  356.          ax := 1 shl 8;
  357.          cx := Top shl 8 + Bot;
  358.          INTR($10,Reg);
  359.        end
  360.     else                           {virtual screen active}
  361.        with Screen[ActiveVScreen]^ do
  362.        begin
  363.            ScanTop := Top;
  364.            ScanBot := Bot;
  365.        end;
  366. end;
  367.  
  368. Procedure HalfCursor;
  369. begin
  370.     If BaseOfScreen = MonoAdr then    
  371.        SizeCursor(8,13)    
  372.     else
  373.        SizeCursor(4,7);    
  374. end; {Proc HalfCursor}
  375.  
  376. Procedure Fullcursor;
  377. begin
  378.     If BaseOfScreen = MonoAdr then
  379.        SizeCursor(0,13)
  380.     else
  381.        SizeCursor(0,7);
  382. end;
  383.  
  384. Procedure OnCursor;
  385. begin
  386.     If BaseOfScreen = MonoAdr then
  387.        SizeCursor(12,13)
  388.     else
  389.        SizeCursor(6,7);
  390. end;
  391.  
  392. Procedure OffCursor;
  393. begin
  394.     Sizecursor(14,0);
  395. end;
  396.  
  397. {++++++++++++++++++++++++++++++++++++++++++++++++++++}
  398. {                                                    }
  399. {   S C R E E N   S A V I N G  R O U T I N E S       }
  400. {                                                    }
  401. {++++++++++++++++++++++++++++++++++++++++++++++++++++}
  402.  
  403. Procedure DisposeScreen(Page:byte);
  404. {Free memory and set pointer to nil}
  405. begin
  406.     If Screen[Page] = nil then
  407.     begin
  408.        WinTTT_Error(6);
  409.        exit;
  410.     end
  411.     else
  412.        W_error := 0;
  413.     FreeMem(Screen[Page]^.ScreenPtr,Screen[Page]^.SavedLines*160);
  414.     Freemem(Screen[Page],SizeOf(Screen[Page]^));
  415.     Screen[page] := nil;
  416.     If ActiveVscreen = Page then
  417.        Activate_Visible_Screen;
  418.     dec(ScreenCounter);
  419. end;
  420.  
  421. Procedure SaveScreen(Page:byte);
  422. {Save screen display and cursor details}
  423. begin
  424.     If (Page > Max_Screens) then
  425.     begin
  426.       WinTTT_Error(1);
  427.       exit;
  428.     end;
  429.     If ((Screen[Page] <> nil) and (DisplayLines <> Screen[Page]^.SavedLines)) then
  430.         DisposeScreen(Page);
  431.     If Screen[Page] = nil then            {need to allocate memory}
  432.     begin
  433.         If MaxAvail < SizeOf(Screen[Page]^) then
  434.         begin
  435.             WinTTT_Error(3);
  436.             exit;
  437.         end;
  438.         GetMem(Screen[Page],SizeOf(Screen[Page]^));
  439.         If MaxAvail < DisplayLines*160 then     {do check in two parts 'cos Maxavail is not same as MemAvail}
  440.         begin
  441.             WinTTT_Error(3);
  442.             Freemem(Screen[Page],SizeOf(Screen[Page]^));
  443.             Screen[Page] := nil;
  444.             exit;
  445.         end;
  446.         GetMem(Screen[Page]^.ScreenPtr,DisplayLines*160);
  447.         Inc(ScreenCounter);
  448.     end;
  449.     With Screen[Page]^ do
  450.     begin
  451.        FindCursor(CursorX,CursorY,ScanTop,ScanBot);     {Save Cursor posn. and shape}
  452.        SavedLines := DisplayLines;
  453.        MoveFromScreen(Mem[BaseOfScreen:0],Screen[Page]^.ScreenPtr^,DisplayLines*80);
  454.     end;
  455.     W_error := 0;
  456. end;
  457.  
  458. Procedure RestoreScreen(Page:byte);
  459. {Display a screen that was previously saved}
  460. begin
  461.     If Screen[Page] = nil then
  462.     begin
  463.        WinTTT_Error(7);
  464.        exit;
  465.     end
  466.     else
  467.        W_error := 0;
  468.     With Screen[Page]^ do
  469.     begin
  470.         MoveToScreen(ScreenPtr^,mem[BaseOfScreen:0], 80*SavedLines);
  471.         PosCursor(CursorX,CursorY);
  472.         SizeCursor(ScanTop,ScanBot);
  473.     end;
  474. end;  {Proc RestoreScreen}
  475.  
  476.  
  477. Procedure PartRestoreScreen(Page,X1,Y1,X2,Y2,X,Y:byte);
  478. {Move from heap to screen, part of saved screen}
  479. Var
  480.    I,width     : byte;
  481.    ScreenAdr,
  482.    PageAdr     : integer;
  483. begin
  484.     If Screen[Page] = nil then
  485.     begin
  486.        WinTTT_Error(7);
  487.        exit;
  488.     end
  489.     else
  490.        W_error := 0;
  491.     Width := succ(X2- X1);
  492.     For I :=  Y1 to Y2 do
  493.     begin
  494.         ScreenAdr := pred(Y+I-Y1)*160 + Pred(X)*2;
  495.         PageAdr   := Pred(I)*160 + Pred(X1)*2;
  496.         MoveToScreen(Mem[Seg(Screen[Page]^.ScreenPtr^):ofs(Screen[Page]^.ScreenPtr^)+PageAdr],
  497.                      Mem[BaseOfScreen:ScreenAdr],
  498.                      width);
  499.     end;
  500. end;
  501.  
  502. Procedure SlideRestoreScreen(Page:byte;Way:Direction);
  503. {Display a screen that was previously saved, with fancy slide}
  504. Var I : byte;
  505. begin
  506.     If Screen[Page] = nil then
  507.     begin
  508.        WinTTT_Error(7);
  509.        exit;
  510.     end
  511.     else
  512.        W_error := 0;
  513.     Case Way of
  514.     Up    : begin
  515.                 For I := DisplayLines downto 1 do
  516.                 begin
  517.                     PartRestoreScreen(Page,
  518.                                       1,1,80,succ(DisplayLines -I),
  519.                                       1,I);
  520.                     Delay(50);
  521.                 end;
  522.             end;
  523.     Down  : begin
  524.                 For I := 1 to DisplayLines do
  525.                 begin
  526.                     PartRestoreScreen(Page,
  527.                                       1,succ(DisplayLines -I),80,DisplayLines,
  528.                                       1,1);
  529.                     Delay(50);  {savor the moment!}
  530.                 end;
  531.             end;
  532.     Left  : begin
  533.                 For I := 1 to 80 do
  534.                 begin
  535.                     PartRestoreScreen(Page,
  536.                                       1,1,I,DisplayLines,
  537.                                       succ(80-I),1);
  538.                 end;
  539.             end;
  540.     Right : begin
  541.                 For I := 80 downto 1 do
  542.                 begin
  543.                     PartRestoreScreen(Page,
  544.                                       I,1,80,DisplayLines,
  545.                                       1,1);
  546.                 end;
  547.             end;
  548.     end; {case}
  549.     PosCursor(Screen[Page]^.CursorX,Screen[Page]^.CursorY);
  550.     SizeCursor(Screen[Page]^.ScanTop,Screen[Page]^.ScanBot);
  551. end;   {Proc SlideRestoreScreen}
  552.  
  553.  
  554. Procedure PartSlideRestoreScreen(Page:byte;Way:Direction;X1,Y1,X2,Y2:byte);
  555. {Display a screen that was previously saved, with fancy slide}
  556. Var I : byte;
  557. begin
  558.     If Screen[Page] = nil then
  559.     begin
  560.        WinTTT_Error(7);
  561.        exit;
  562.     end
  563.     else
  564.        W_error := 0;
  565.     Case Way of
  566.     Up    : begin
  567.                 For I := Y2 downto Y1 do
  568.                 begin
  569.                     PartRestoreScreen(Page,
  570.                                       X1,Y1,X2,Y1+Y2-I,
  571.                                       X1,I);
  572.                     Delay(50);
  573.                 end;
  574.             end;
  575.     Down  : begin
  576.                 For I := Y1 to Y2 do
  577.                 begin
  578.                     PartRestoreScreen(Page,
  579.                                       X1,Y1+Y2 -I,X2,Y2,
  580.                                       X1,Y1);
  581.                     Delay(50);  {savor the moment!}
  582.                 end;
  583.             end;
  584.     Left  : begin
  585.                 For I := X1 to X2 do
  586.                 begin
  587.                     PartRestoreScreen(Page,
  588.                                       X1,Y1,I,Y2,
  589.                                       X1+X2-I,Y1);
  590.                 end;
  591.             end;
  592.     Right : begin
  593.                 For I := X2 downto X1 do
  594.                 begin
  595.                     PartRestoreScreen(Page,
  596.                                       I,Y1,X2,Y2,
  597.                                       X1,Y1);
  598.                 end;
  599.             end;
  600.     end; {case}
  601. end;   {Proc PartSlideRestoreScreen}
  602.  
  603.  
  604. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  605. {                                                                              }
  606. {     V I R T U A L    S C R E E N    S P E C I F I C   P R O C E D U R E S    }
  607. {                                                                              }
  608. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  609.  
  610. Procedure Clear_Vscreen(page:byte);
  611. var
  612.    Tseg, Tofs : word;
  613. begin
  614.     If Screen[Page] = nil then
  615.     begin
  616.        WinTTT_Error(8);
  617.        exit;
  618.     end
  619.     else
  620.        W_error := 0;
  621.     Tseg := Vseg;
  622.     Tofs := Vofs;
  623.     Vseg := Seg(Screen[Page]^.ScreenPtr^);
  624.     Vofs := Ofs(Screen[Page]^.ScreenPtr^);
  625.     ClearText(1,1,80,Screen[Page]^.SavedLines,yellow,black);
  626.     Vseg := Tseg;
  627.     Vofs := Tofs;
  628. end;
  629.  
  630. Procedure CreateScreen(Page:byte;Lines:byte);
  631. begin
  632.     W_error := 0;
  633.     If (Page > Max_Screens) then
  634.     begin
  635.        WinTTT_Error(1);
  636.        exit;
  637.     end;
  638.     If ((Screen[Page] <> nil) and (Lines <> Screen[Page]^.SavedLines)) then
  639.         DisposeScreen(Page);
  640.     If Screen[Page] = nil then            {need to allocate memory}
  641.     begin
  642.         If MaxAvail < SizeOf(Screen[Page]^) then
  643.         begin
  644.             WinTTT_Error(3);
  645.             exit;
  646.         end;
  647.         GetMem(Screen[Page],SizeOf(Screen[Page]^));
  648.         If MaxAvail < Lines*160 then     {do check in two parts 'cos Maxavail is not same as MemAvail}
  649.         begin
  650.             WinTTT_Error(3);
  651.             Freemem(Screen[Page],SizeOf(Screen[Page]^));
  652.             Screen[Page] := nil;
  653.             exit;
  654.         end;
  655.         GetMem(Screen[Page]^.ScreenPtr,Lines*160);
  656.         Inc(ScreenCounter);
  657.     end;
  658.     With Screen[Page]^ do
  659.     begin
  660.         If BaseOfScreen = $B000 then
  661.         begin
  662.             ScanTop := 12;
  663.             ScanBot := 13;
  664.         end
  665.         else
  666.         begin
  667.             ScanTop := 6;
  668.             ScanBot := 7;
  669.         end;
  670.         CursorX := 1;
  671.         CursorY := 1;
  672.         SavedLines := Lines;
  673.         Clear_Vscreen(Page);
  674.     end;
  675. end;
  676.  
  677. Procedure Activate_Visible_Screen;
  678. begin
  679.     VSeg := BaseOfScreen;
  680.     VOfs := 0;
  681.     ActiveVscreen := 0;
  682. end;
  683.  
  684. Procedure Activate_Virtual_Screen(Page:byte);
  685. {Page zero signifies the visible screen}
  686. begin
  687.     If Screen[Page] = nil then
  688.        WinTTT_Error(4)
  689.     else
  690.     begin
  691.        W_error := 0;
  692.        If Page = 0 then
  693.           Activate_Visible_Screen
  694.        else
  695.        begin
  696.            VSeg := Seg(Screen[Page]^.ScreenPtr^);
  697.            VOfs := Ofs(Screen[Page]^.ScreenPtr^);
  698.            ActiveVScreen := page;
  699.        end;
  700.     end;
  701. end;
  702.  
  703. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  704. {                                                                              }
  705. {     V I S I B L E    S C R E E N    S P E C I F I C   P R O C E D U R E S    }
  706. {                                                                              }
  707. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  708.  
  709. Procedure SetCondensedLines;
  710. begin
  711.     If EGAVGASystem then
  712.     begin
  713.         W_Error := 0;
  714.         TextMode(Lo(LastMode)+Font8x8);
  715.         DisplayLines := succ(Hi(WindMax));
  716.     end
  717.     else
  718.         W_Error := 12;
  719. end;  {proc SetCondensedDisplay}
  720.  
  721. Procedure Set25Lines;
  722. begin
  723.     TextMode(Lo(LastMode));
  724.     DisplayLines := succ(Hi(WindMax));
  725. end;
  726.  
  727.  
  728. Procedure CopyScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
  729. {copies text and attributes from one part of screen to another}
  730. Var
  731.    S : word;
  732.    SPtr : pointer;
  733. begin
  734.     W_error := 0;
  735.     S := succ(Y2-Y1)*succ(X2-X1)*2;
  736.     If Maxavail < S then
  737.        WinTTT_Error(9)
  738.     else
  739.     begin
  740.         GetMem(SPtr,S);
  741.         PartSave(X1,Y1,X2,Y2,SPtr^);
  742.         PartRestore(X,Y,X+X2-X1,Y+Y2-Y1,SPtr^);
  743.         FreeMem(Sptr,S);
  744.     end;
  745. end; {CopyScreenBlock}
  746.  
  747. Procedure MoveScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
  748. {Moves text and attributes from one part of screen to another,
  749.  replacing with Replace_Char}
  750. const
  751.   Replace_Char = ' ';
  752. Var
  753.    S : word;
  754.    SPtr : pointer;
  755.    I : Integer;
  756.    ST : string;
  757. begin
  758.     W_error := 0;
  759.     S := succ(Y2-Y1)*succ(X2-X1)*2;
  760.     If Maxavail < S then
  761.        WinTTT_Error(9)
  762.     else
  763.     begin
  764.         GetMem(SPtr,S);
  765.         PartSave(X1,Y1,X2,Y2,SPtr^);
  766.         St := Replicate(succ(X2-X1),Replace_Char);
  767.         For I := Y1 to Y2 do
  768.             PlainWrite(X1,I,St);
  769.         PartRestore(X,Y,X+X2-X1,Y+Y2-Y1,SPtr^);
  770.         FreeMem(Sptr,S);
  771.     end;
  772. end; {Proc MoveScreenBlock}
  773.  
  774. Procedure Scroll(Way:direction;X1,Y1,X2,Y2:byte);
  775. {used for screen scrolling, uses Copy & Plainwrite for speed}
  776. const
  777.   Replace_Char = ' ';
  778. var
  779.   I : integer;
  780. begin
  781.     W_error := 0;
  782.     Case Way of
  783.     Up   : begin
  784.                CopyScreenBlock(X1,succ(Y1),X2,Y2,X1,Y1);
  785.                PlainWrite(X1,Y2,replicate(succ(X2-X1),Replace_Char));
  786.            end;
  787.     Down : begin
  788.                CopyScreenBlock(X1,Y1,X2,pred(Y2),X1,succ(Y1));
  789.                PlainWrite(X1,Y1,replicate(succ(X2-X1),Replace_Char));
  790.            end;
  791.     Left : begin
  792.                CopyScreenBlock(succ(X1),Y1,X2,Y2,X1,Y1);
  793.                For I := Y1 to Y2 do
  794.                    PlainWrite(X2,I,Replace_Char);   {5.01}
  795.            end;
  796.     Right: begin
  797.                CopyScreenBlock(X1,Y1,pred(X2),Y2,succ(X1),Y1);
  798.                For I := Y1 to Y2 do
  799.                    PlainWrite(X1,I,Replace_Char);   {5.01}
  800.            end;
  801.     end; {case}
  802. end;
  803.  
  804. procedure CreateWin(x1,y1,x2,y2,F,B,boxtype:integer);
  805. {called by MkWin and GrowMkWin}
  806. begin
  807.     If WindowCounter >= Max_Windows then
  808.     begin
  809.        WinTTT_Error(2);
  810.        exit;
  811.     end;
  812.     If MaxAvail < sizeOf(Win[WindowCounter]^) then
  813.     begin
  814.        WinTTT_Error(3);
  815.        exit;
  816.     end
  817.     else
  818.        W_error := 0;
  819.     Inc(WindowCounter);
  820.     GetMem(Win[WindowCounter],sizeof(Win[WindowCounter]^));    {allocate space}
  821.     If (BoxType in [5..9]) and (X1 > 1) then     {is there a drop shadow}
  822.     begin
  823.         X1 := pred(X1);    {increase dimensions for the box}
  824.         Y2 := succ(Y2);
  825.     end;
  826.     If MaxAvail < succ(Y2-Y1)*succ(X2-X1)*2 then
  827.     begin
  828.        WinTTT_Error(3);
  829.        exit;
  830.     end;
  831.     GetMem(Win[WindowCounter]^.ScreenPtr,succ(Y2-Y1)*succ(X2-X1)*2);
  832.     PartSave(X1,Y1,X2,Y2,Win[WindowCounter]^.ScreenPtr^);
  833.     with Win[WindowCounter]^ do
  834.     begin
  835.       Coord[1] := X1;
  836.       Coord[2] := Y1;
  837.       Coord[3] := X2;
  838.       Coord[4] := Y2;
  839.       FindCursor(CursorX,CursorY,ScanTop,ScanBot);
  840.     end;  {with}
  841. end; {Proc CreateWin}
  842.  
  843. procedure mkwin(x1,y1,x2,y2,F,B,boxtype:integer);
  844. {Main procedure for creating window}
  845. var I : integer;
  846. begin
  847.     If ActiveVscreen <> 0 then
  848.     begin
  849.         W_error := 10;
  850.         exit;
  851.     end
  852.     else
  853.         W_error := 0;
  854.     CreateWin(X1,Y1,X2,Y2,F,B,Boxtype);
  855.     If (BoxType in [5..9]) and (X1 > 1) then
  856.        FBox(x1,y1,x2,y2,F,B,boxtype-shadow)
  857.     else
  858.        FBox(x1,y1,x2,y2,F,B,boxtype);
  859.     If (BoxType in [5..9]) and (X1 > 1) then     {is there a drop shadow}
  860.     begin
  861.         For I := succ(Y1) to succ(Y2) do
  862.             WriteAt(pred(X1),I,Shadcolor,black,chr(219));
  863.         WriteAt(X1,succ(Y2),Shadcolor,black,
  864.                 replicate(X2-succ(X1),chr(219)));
  865.     end;
  866. end;
  867.  
  868. procedure GrowMKwin(x1,y1,x2,y2,F,B,boxtype:integer);
  869. {same as MKwin but window explodes}
  870. var I : integer;
  871. begin
  872.     If ActiveVscreen <> 0 then
  873.     begin
  874.         W_error := 10;
  875.         exit;
  876.     end
  877.     else
  878.         W_error := 0;
  879.     CreateWin(X1,Y1,X2,Y2,F,B,Boxtype);
  880.     If (BoxType in [5..9]) and (X1 > 1) then
  881.        GrowFBox(x1,y1,x2,y2,F,B,boxtype-shadow)
  882.     else
  883.        GrowFBox(x1,y1,x2,y2,F,B,boxtype);
  884.     If (BoxType in [5..9]) and (X1 > 1) then     {is there a drop shadow}
  885.     begin
  886.         For I := succ(Y1) to succ(Y2) do
  887.             WriteAt(pred(X1),I,Shadcolor,black,chr(219));
  888.         WriteAt(X1,succ(Y2),Shadcolor,black,
  889.                 replicate(X2-succ(X1),chr(219)));
  890.     end;
  891. end;
  892.  
  893. Procedure RmWin;
  894. begin
  895.     If ActiveVscreen <> 0 then
  896.     begin
  897.         W_error := 10;
  898.         exit;
  899.     end
  900.     else
  901.         W_error := 0;
  902.     If WindowCounter > 0 then
  903.     begin
  904.         with  Win[WindowCounter]^ do
  905.         begin
  906.             PartRestore(Coord[1],Coord[2],Coord[3],Coord[4],ScreenPtr^);
  907.             PosCursor(CursorX,CursorY);
  908.             SizeCursor(ScanTop,ScanBot);
  909.             FreeMem(ScreenPtr,succ(Coord[4]-coord[2])*succ(coord[3]-coord[1])*2);
  910.             FreeMem(Win[WindowCounter],sizeof(Win[WindowCounter]^));
  911.         end; {with}
  912.         Dec(WindowCounter);
  913.     end;
  914. end;
  915.  
  916. procedure TempMessageCh(X,Y,F,B:integer;St:strscreen;var Ch : char);
  917. var
  918.  CX,CY,CT,CB,I,locC:integer;
  919.  SavedLine : array[1..160] of byte;
  920. begin
  921.     If ActiveVscreen <> 0 then
  922.     begin
  923.         W_error := 11;
  924.         exit;
  925.     end
  926.     else
  927.         W_error := 0;
  928.     PartSave(X,Y,pred(X)+length(St),Y,SavedLine);
  929.     WriteAT(X,Y,F,B,St);
  930.     Ch := GetKey;
  931.     PartRestore(X,Y,pred(X)+length(St),Y,SavedLine);
  932. end;
  933.  
  934. Procedure TempMessage(X,Y,F,B:integer;St:strscreen);
  935. var Ch : char;
  936. begin
  937.     TempMessageCH(X,Y,F,B,ST,Ch);
  938. end;              
  939.  
  940. Procedure TempMessageBoxCh(X1,Y1,F,B,BoxType:integer;St:strscreen;var Ch : char);
  941. begin
  942.     If ActiveVscreen <> 0 then
  943.     begin
  944.         W_error := 11;
  945.         exit;
  946.     end
  947.     else
  948.         W_error := 0;
  949.     MkWin(X1,Y1,succ(X1)+length(St),Y1+2,F,B,Boxtype);
  950.     WriteAt(succ(X1),Succ(Y1),F,B,St);
  951.     Ch := getKey;
  952.     Rmwin;
  953. end;
  954.  
  955. Procedure TempMessageBox(X1,Y1,F,B,BoxType:integer;St:strscreen);
  956. var Ch : char;
  957. begin
  958.     TempMessageBoxCh(X1,Y1,F,B,Boxtype,St,Ch);
  959. end;
  960.  
  961. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  962.  
  963. Procedure InitWinTTT;
  964. {set Pointers to nil for validity checking}
  965. Var
  966.   I : integer;
  967.   X,Y : byte;
  968. begin
  969.     For I := 1 to Max_Screens do
  970.         Screen[I] := nil;
  971.     StartMode := LastMode;           { record the initial state of screen when program was executed}
  972.     DisplayLines := succ(Hi(WindMax));
  973.     FindCursor(X,Y,StartTop,StartBot);
  974. end;
  975.  
  976.  
  977. Procedure Reset_StartUp_Mode;
  978. {resets monitor mode and cursor settings to the state they
  979.  were in at program startup}
  980. begin
  981.     TextMode(StartMode);
  982.     SizeCursor(StartTop,StartBot);
  983. end; {proc StartUp_Mode}
  984.  
  985. begin
  986.     InitWinTTT;
  987.     W_error := 0;
  988.     W_fatal := false;   {don't terminate program if fatal error}
  989.     Shadcolor := darkgray;
  990. end.
  991.